package hu.plajko.server;

import hu.plajko.client.GreetingService;
import hu.plajko.server.jdo.Data;
import hu.plajko.server.jdo.Notification;
import hu.plajko.shared.rpc.NotificationRPC;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import javax.jdo.Query;

import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Text;
import com.google.gwt.user.client.rpc.SerializationException;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

/**
 * The server side implementation of the RPC service.
 */
public class GreetingServiceImpl extends RemoteServiceServlet implements GreetingService {

	private static final long serialVersionUID = 1L;

	private static final PersistenceManagerFactory pmfInstance = JDOHelper.getPersistenceManagerFactory("transactions-optional");

	// {
	// ChannelServiceFactory.getChannelService().createChannel("testapp");
	// }

	@Override
	public String generate(final String input) throws SerializationException {

		PersistenceManager pm = pmfInstance.getPersistenceManager();
		try {
			pm.makePersistent(new Data(input, new Date(), getThreadLocalRequest().getRemoteAddr()));

		} finally {
			pm.close();
		}

		// ChannelServiceFactory.getChannelService().createChannel("testapp");
		// try {
		// ChannelService cs = ChannelServiceFactory.getChannelService();
		// cs.sendMessage(new ChannelMessage("testapp", "Hello!"));
		// } catch (Exception e) {
		// e.printStackTrace();
		// }

		String query = "select from " + Data.class.getName() + " order by timestamp desc";

		PersistenceManager pm2 = pmfInstance.getPersistenceManager();
		List<Data> result = (List<Data>) pm2.newQuery(query).execute();

		StringBuilder sb = new StringBuilder();
		sb.append("<table border=\"1\">");
		for (Data data : result) {
			sb.append("<tr><td>" + data.getKey().getId() + "</td><td>" + data.getTimestamp() + "</td><td>" + data.getData() + "</td><td>" + data.getAddress() + "</td></tr>");
		}
		sb.append("</table>");

		return sb.toString();
	}

	@Override
	public List<NotificationRPC> getNotifications() throws SerializationException {
		PersistenceManager pm = null;
		try {
			String query = "select from " + Notification.class.getName();
			pm = pmfInstance.getPersistenceManager();
			List<Notification> result = (List<Notification>) pm.newQuery(query).execute();
			List<NotificationRPC> ret = new ArrayList<NotificationRPC>();
			for (Notification n : result)
				ret.add(Notification.toRPC(n));
			return ret;
		} catch (Throwable t) {
			t.printStackTrace();
			throw new SerializationException(t);
		} finally {
			if (pm != null)
				pm.close();
		}
	}

	@Override
	public String updateNotification(NotificationRPC nr) throws SerializationException {
		PersistenceManager pm = null;
		try {
			pm = pmfInstance.getPersistenceManager();

			System.out.println("update object: " + nr.toString());

			Notification n = nr.getId() == null ? new Notification() : pm.getObjectById(Notification.class, KeyFactory.stringToKey(nr.getId()));
			n.setText(new Text(nr.getText()));
			n.setLeft(nr.getLeft());
			n.setTop(nr.getTop());
			n.setWidth(nr.getWidth());
			n.setHeight(nr.getHeight());
			n.setZindex(nr.getZindex());
			pm.makePersistent(n);

			return KeyFactory.keyToString(n.getId());
		} catch (Throwable t) {
			throw new SerializationException(t);
		} finally {
			if (pm != null)
				pm.close();
		}

	}

	@Override
	public void removeNotification(NotificationRPC n) throws SerializationException {
		PersistenceManager pm = null;
		try {
			pm = pmfInstance.getPersistenceManager();
			pm.deletePersistent(pm.getObjectById(Notification.class, KeyFactory.stringToKey(n.getId())));
		} catch (Throwable t) {
			throw new SerializationException(t);
		} finally {
			if (pm != null)
				pm.close();
		}

	}

	@Override
	public void clearNotifications() throws SerializationException {
		PersistenceManager pm = null;
		try {
			pm = pmfInstance.getPersistenceManager();
			Query query = pm.newQuery(Notification.class);
			query.deletePersistentAll();
		} catch (Throwable t) {
			throw new SerializationException(t);
		} finally {
			if (pm != null)
				pm.close();
		}

	}

	@Override
	public NotificationRPC getData(String id) throws SerializationException {
		PersistenceManager pm = null;
		try {
			pm = pmfInstance.getPersistenceManager();
			Notification n = pm.getObjectById(Notification.class, KeyFactory.stringToKey(id));
			return Notification.toRPC(n);
		} catch (Throwable t) {
			throw new SerializationException(t);
		} finally {
			if (pm != null)
				pm.close();
		}
	}

}
